﻿#region Header
/********************************************************           
 * TQX   
 *                                                         
 * Author:  Richard Barclay  (phphanatic at gmail dot com) 
 * 
 * Copyright: 2009 Richard Barclay
 * 
 * License: GNU General Public License (GPL)
 *     
 * This file is part of the Intergr8.GoogleVisualization library.
 *
 *   The Intergr8.GoogleVisualization library is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *  Intergr8.GoogleVisualization library is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with Intergr8.GoogleVisualization library.  If not, see <http://www.gnu.org/licenses/>.
 *                                                         
 * Purpose:  Manage and process the TQX portion of a Google Visualization request
 *                                                         
 * Usage:                                                  
 *      Internally managed
 *      
 ********************************************************/
#endregion

namespace Intergr8.GoogleVisualization
{
    using System;
    using System.Collections.Specialized;
    using System.Text;
    //using Intergr8.GoogleVisualization.Interfaces;

    /// <summary>
    /// Manage and process the TQX portion of a Google Visualization request
    /// </summary>
    public class TQX //: VisualizationBase, ITQX
    {
        #region Static consts
        private const string PARAM_REQUESTID = "reqId";
        private const string PARAM_VERSION = "version";
        private const string PARAM_SIGNATURE = "sig";
        private const string PARAM_OUTPUTFORMAT = "out";
        private const string PARAM_OUTPUTFORMAT_JSON = "json";
        private const string PARAM_OUTPUTFORMAT_CSV = "csv";
        private const string PARAM_OUTPUTFORMAT_HTML = "html";
        private const string PARAM_OUTPUTFORMAT_TSVEXCEL = "tsv-excel";
        private const string PARAM_RESPONSEHANDLER = "responseHandler";
        private const string PARAM_OUTPUTFILENAME = "outFileName";

        private static string DEFAULT_RESPONSEHANDLER = "google.visualization.Query.setResponse";
        private static string DEFAULT_VERSION = "0.6";
        private static string DEFAULT_OUTPUTFILENAME = "";
        private static int DEFAULT_REQUESTID = 0;
        private static int DEFAULT_SIGNATURE = 0;
        private static string DEFAULT_OUTPUTFORMAT = "json";
        #endregion        
        
        #region Attributes


        /// <summary>
        /// A numeric identifier for this request. This is used so that if a client sends multiple requests before receiving a response,
        /// the data source can identify the response with the proper request. Send this value back in the response
        /// </summary>
        private int _reqId = DEFAULT_REQUESTID;

        /// <summary>
        /// Protocol Version Number
        /// </summary>
        private string _version = DEFAULT_VERSION;

        /// <summary>
        /// A hash of the DataTable last sent to the client
        /// </summary>
        private int _sig = DEFAULT_SIGNATURE;

        /// <summary>
        /// 
        /// </summary>
        private string _out = DEFAULT_OUTPUTFORMAT;

        /// <summary>
        /// 
        /// </summary>


        /// <summary>
        /// 
        /// </summary>
        private string _responseHandler = "";

        /// <summary>
        /// 
        /// </summary>
        private string _outputFileName = "";

        #endregion

        public bool IsValid { get; private set; }

        /// <summary>
        /// Default TQX
        /// </summary>
        public TQX()
        {
            Init();
        }

        private void Init()
        {
            // Set up default state
            _reqId = DEFAULT_REQUESTID;
            _version = DEFAULT_VERSION;
            _sig = DEFAULT_SIGNATURE;
            _out = DEFAULT_OUTPUTFORMAT;
            _responseHandler = DEFAULT_RESPONSEHANDLER;
            _outputFileName = DEFAULT_OUTPUTFILENAME;

            // Valid with default settings
            IsValid = true;
        }

        /// <summary>
        /// Specified TQX object
        /// tqx=version:0.6;reqId:1;sig:5277771;out:json; responseHandler:myQueryHandler
        /// </summary>
        /// <param name="tqx"></param>
        public TQX(string tqx) //:base()
        {
            try
            {
                // If we have been passed a null, treat as an empty string
                if (tqx == null)
                {
                    tqx = String.Empty;
                }

                // Initialist the defaults
                Init();


                NameValueCollection nvc = new NameValueCollection();
                Array nameval = null;


                // split on ;
                Array namevalues = tqx.Split(';');
                if (namevalues.Length > 0)
                {
                    foreach (string entry in namevalues)
                    {
                        if (entry.Length > 0)
                        {
                            nameval = entry.Split(':');
                            nvc.Add(nameval.GetValue(0).ToString(), nameval.GetValue(1).ToString());
                        }
                    }

                }
            

                // Request ID is only required if a tqx attribute has been passed in the request
                if (tqx.Length > 0)
                {                    
                    if (nvc.GetValues(PARAM_REQUESTID) != null)
                    {
                        _reqId = int.Parse((nvc.GetValues(PARAM_REQUESTID)[0]).ToString());
                    }
                    else
                    {
                        IsValid = false;
                        throw new ArgumentOutOfRangeException("reqId", "TQX::~ctor. Missing reqID");
                    }
                }

                // populate the attributes


                // Version
                if (nvc.GetValues(PARAM_VERSION) != null)
                {
                    _version = (nvc.GetValues(PARAM_VERSION)[0]).ToString();
                }

                // Signature
                if (nvc.GetValues(PARAM_SIGNATURE) != null)
                {
                    _sig = Convert.ToInt32( (nvc.GetValues(PARAM_SIGNATURE)[0]).ToString());
                }

                if (nvc.GetValues(PARAM_OUTPUTFORMAT) != null)
                {
                    switch (nvc.GetValues(PARAM_OUTPUTFORMAT)[0])
                    {
                        case PARAM_OUTPUTFORMAT_JSON:
                            _out = "json";
                            break;
                        case PARAM_OUTPUTFORMAT_CSV:
                            _out = "csv";
                            break;
                        case PARAM_OUTPUTFORMAT_HTML:
                            _out = "html";
                            break;
                        case PARAM_OUTPUTFORMAT_TSVEXCEL:
                            _out = "tsvexcel";
                            break;
                        default:
                            _out = "";
                            break;
                    }
                }

                if (nvc.GetValues(PARAM_RESPONSEHANDLER) != null)
                {
                    _responseHandler = (nvc.GetValues(PARAM_RESPONSEHANDLER)[0]).ToString();
                }

                if (nvc.GetValues(PARAM_OUTPUTFILENAME) != null)
                {
                    _outputFileName = (nvc.GetValues(PARAM_OUTPUTFILENAME)[0]).ToString();
                }

                //Mark this object as valid on completion of parsing
                IsValid = true;

            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.TraceError("TQX::~ctor. Exception {0}", ex.Message);
                IsValid = false;
                throw ex;
            }

        }


        /// <summary>
        /// A numeric identifier for this request. 
        /// This is used so that if a client sends multiple requests before receiving a response,
        /// the data source can identify the response with the proper request.
        /// </summary>
        public int ReqId
        {
            get { return _reqId; }
        }

        /// <summary>
        /// The version number of the Google Visualization protocol. Current version is 0.6. If not sent, assume the latest version
        /// </summary>
        public string Version
        {
            get { return _version; }
        }

        /// <summary>
        /// A hash of the DataTable sent to this client in any previous requests to this data source. 
        /// This is an optimization to avoid sending identical data to a client twice.
        /// </summary>
        public int Sig
        {
            get { return _sig; }
        }

        /// <summary>
        ///  The  format for the returned data
        /// </summary>
        public string Output
        {
            get { return _out; }
        }

        /// <summary>
        /// The string name of the JavaScript handling function on the client page that will be called with the response.
        /// If not included in the request, the value is "google.visualization.Query.setResponse"
        /// </summary>
        public string ResponseHandler
        {
            get { return _responseHandler; }
        }

        /// <summary>
        ///  If you specify out:csv or out:tsvexcel, you can optionally request the file name specified here
        /// </summary>
        public string OutputFileName
        {
            get { return _outputFileName; }
        }

    }
}
